/**
 * Copyright 2008 Wink Saville
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
/**
 * There is a single instance of a Deserializer and
 * two public entry points. Deserializer.register to
 * register a deser for an object and deserialize which
 * uses parseJSON to convert the string to javascript
 * objects and then invokes the registered deser routines
 * to actually create the real objects.
 *
 * The form of a serialized object is a JSON object with
 * one key and one value. The key is used to to lookup
 * the appropriate deser function in Deserialize.map.
 * The deser function recieves the value field and is
 * returns an instance of the object.
 */
  
 if (typeof Deserializer == "undefined") {

    /*
     * Private Constructor
     */
    function _Deserializer() {
        this.map = new Object;
    }

    /*
     * Deserialize a string
     */
    _Deserializer.prototype.deserialize =  function (jsonString) {
        return this._deser(jsonString.parseJSON());
    }
    
    /*
     * Register a deser
     */
    _Deserializer.prototype.register = function (id, deser) {
        this.map[id] = deser;
    }
    
    /*
     * Semi private function that calls the deser function
     * for a jason object. Can/is used by registered
     * deser routines to recursively deserialize nested
     * objects. See Msg.deser as an example.
     */
    _Deserializer.prototype._deser = function (jo) {
        if (jo && typeof jo === 'object') {
            for (objectProp in jo) {
                if (objectProp && typeof objectProp === 'string') {
                    deser = this.map[objectProp];
                    if (deser && typeof deser === 'function') {
                        return deser(jo[objectProp]);
                    } else {
                        return null;
                    }
                } else {
                    return null;
                }
            }
        } else {
            return null;
        }
    }
    
    /*
     * The Deserializer instance
     */
    Deserializer = new _Deserializer();
}